<?php
namespace Leaps\Cache;
use Closure, ArrayAccess;

class Repository implements ArrayAccess {

	/**
	 * 缓存存储实例
	 *
	 * @var \Leaps\Cache\StoreInterface
	 */
	protected $store;

	/**
	 * 默认时间
	 *
	 * @var int
	 */
	protected $default = 60;

	/**
	 * 创建一个新的缓存驱动实例。
	 *
	 * @param  \Leaps\Cache\StoreInterface  $store
	 */
	public function __construct(AdapterInterface $store)
	{
		$this->store = $store;
	}

	/**
	 * 判断缓存是否存在
	 *
	 * @param  string  $key
	 * @return bool
	 */
	public function has($key)
	{
		return ! is_null($this->get($key));
	}

	/**
	 * 获取缓存
	 *
	 * @param  string  $key
	 * @param  mixed   $default
	 * @return mixed
	 */
	public function get($key, $default = null)
	{
		$value = $this->store->get($key);
		return ! is_null($value) ? unserialize ( $value ) : value($default);
	}

	/**
	 * 设置缓存
	 * @param unknown $key
	 * @param unknown $value
	 * @param number $minutes
	 */
	public function set($key, $value, $minutes = false){
	    if(!$minutes) $minutes = $this->getDefaultCacheTime();
	    return $this->store->set ( $key, serialize ( $value ), $minutes );
	}

	/**
	 * 添加缓存
	 *
	 * @param  string  $key
	 * @param  mixed   $value
	 * @param  int     $minutes
	 * @return void
	 */
	public function add($key, $value, $minutes = false)
	{
	    if(!$minutes) $minutes = $this->getDefaultCacheTime();
		if (is_null($this->get($key))) $this->set($key, $value, $minutes);
	}

	/**
	 * 获取缓存或默认值
	 *
	 * @param  string   $key
	 * @param  int      $minutes
	 * @param  Closure  $callback
	 * @return mixed
	 */
	public function remember($key, $minutes = false, Closure $callback)
	{
	    if(!$minutes) $minutes = $this->getDefaultCacheTime();
		if ($this->has($key)) return $this->get($key);
		$this->set($key, $value = $callback(), $minutes);
		return $value;
	}

	/**
	 * 获取永久缓存
	 *
	 * @param  string   $key
	 * @param  Closure  $callback
	 * @return mixed
	 */
	public function sear($key, Closure $callback)
	{
		return $this->rememberForever($key, $callback);
	}

	/**
	 * 获取永久缓存
	 *
	 * @param  string   $key
	 * @param  Closure  $callback
	 * @return mixed
	 */
	public function rememberForever($key, Closure $callback)
	{
		if ( ! is_null($value = $this->get($key)))
		{
			return $value;
		}
		$this->forever($key, $value = $callback());
		return $value;
	}

	/**
	 * 得到默认的缓存时间。
	 *
	 * @return int
	 */
	public function getDefaultCacheTime()
	{
		return $this->default;
	}

	/**
	 * 设置默认的缓存时间分钟。
	 *
	 * @param  int   $minutes
	 * @return void
	 */
	public function setDefaultCacheTime($minutes)
	{
		$this->default = $minutes;
	}

	/**
	 * 获取缓存存储的实例。
	 *
	 * @return \Leaps\Cache\StoreInterface
	 */
	public function getStore()
	{
		return $this->store;
	}

	/**
	 * 判断缓存是否存在
	 *
	 * @param  string  $key
	 * @return bool
	 */
	public function offsetExists($key)
	{
		return $this->has($key);
	}

	/**
	 * 获取缓存
	 *
	 * @param  string  $key
	 * @return mixed
	 */
	public function offsetGet($key)
	{
		return $this->get($key);
	}

	/**
	 * 设置缓存
	 *
	 * @param  string  $key
	 * @param  mixed   $value
	 * @return void
	 */
	public function offsetSet($key, $value)
	{
		$this->set($key, $value, $this->default);
	}

	/**
	 * 删除缓存
	 *
	 * @param  string  $key
	 * @return void
	 */
	public function offsetUnset($key)
	{
		return $this->forget($key);
	}

	/**
	 * 动态传递缺少的方法到存储实例
	 *
	 * @param  string  $method
	 * @param  array   $parameters
	 * @return mixed
	 */
	public function __call($method, $parameters)
	{
		return call_user_func_array(array($this->store, $method), $parameters);
	}

}